package org.redmagic.location.web;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.Map;
import java.util.Properties;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.redmagic.Request;
import org.redmagic.Response;
import org.redmagic.ResponseDecoder;
import org.redmagic.TransactionManager;

public class BulkTransactionManager implements TransactionManager {

	private final Map<String, ResponseDecoder> responseDecoders;
	private final HttpClient httpClient;
	
	public BulkTransactionManager(Map<String, ResponseDecoder> responseDecoders) {
		this.responseDecoders = responseDecoders;
		this.httpClient = new DefaultHttpClient();
	}
	
	@Override
	public Response execute(URI uri, Request redMagicRequest) {
		try {
			return tryExecute(uri, redMagicRequest);
		} catch (Exception e) {
			throw new RuntimeException("Transaction failed", e);
		}
	}
	
	private Response tryExecute(URI uri, Request redMagicRequest) throws ClientProtocolException, IOException {
		HttpUriRequest request = prepareRequest(uri, redMagicRequest);
		HttpResponse httpResponse = httpClient.execute(request);
		Properties response = handleResponse(httpResponse);
		
		return new SimpleResponse(response);
	}
	
	private HttpUriRequest prepareRequest(URI uri, Request redMagicRequest) throws UnsupportedEncodingException {
		HttpPost post = new HttpPost(uri);
        post.addHeader(HttpHeaders.CONTENT_TYPE, redMagicRequest.getMediaType());
        post.setEntity(new StringEntity(redMagicRequest.marshall()));
        return post;
	}
	
	private Properties handleResponse(HttpResponse httpResponse) throws IllegalStateException, IOException {
		HttpEntity responseEntity = httpResponse.getEntity();
		ResponseDecoder responseDecoder = getResponseDecoder(responseEntity);
		return responseDecoder.decode(responseEntity.getContent());
	}
	
	private ResponseDecoder getResponseDecoder(HttpEntity responseEntity) {
		Header contentType = responseEntity.getContentType();
		return responseDecoders.get(contentType.getValue());
	}
}
